﻿using MVCScaffolder.Model;
using EnvDTE;
using Microsoft.AspNet.Scaffolding;
using System.Collections.Generic;
using MVCScaffolder;
using Microsoft.AspNet.Scaffolding.NuGet;
using System;
using System.IO;

namespace MVCScaffolder
{
    public class CustomCodeGenerator : CodeGenerator
    {
       // CustomViewModel _viewModel;
        CodeGenerationContext context;

        /// <summary>
        /// Constructor for the custom code generator
        /// </summary>
        /// <param name="context">Context of the current code generation operation based on how scaffolder was invoked(such as selected project/folder) </param>
        /// <param name="information">Code generation information that is defined in the factory class.</param>
        public CustomCodeGenerator(
            CodeGenerationContext context,
            CodeGeneratorInformation information)
            : base(context, information)
        {
            this.context = context;
           // _viewModel = new CustomViewModel(Context);
        }

        private CodeGeneratorProperty CodeGeneratorProperty;

        /// <summary>
        /// Any UI to be displayed after the scaffolder has been selected from the Add Scaffold dialog.
        /// Any validation on the input for values in the UI should be completed before returning from this method.
        /// </summary>
        /// <returns></returns>
        public override bool ShowUIAndValidate()
        {
            // Bring up the selection dialog and allow user to select a model type

            Form1 f = new Form1(context,this);
            f.ShowDialog();
            CodeGeneratorProperty = f.CodeGeneratorProperty;

            //SelectModelWindow window = new SelectModelWindow(_viewModel);
            //bool? showDialog = window.ShowDialog();
            return true;
        }

        private String GetProjectDirectory(EnvDTE.Project P)
        {
            return P.Properties.Item("FullPath").Value.ToString();
        }

        private void UpdateHomeIndex()
        {

            String ProjectDirectoryName = GetProjectDirectory( this.context.ActiveProject );
            String ViewsDirectoryName = System.IO.Path.Combine(ProjectDirectoryName, "Views");
            String ViewIndexFileName = System.IO.Path.Combine(ViewsDirectoryName, "Home", "Index.cshtml");

            if (System.IO.File.Exists(ViewIndexFileName))
            {
                String ViewIndexText = System.IO.File.ReadAllText(ViewIndexFileName);
                String LinkSourceCode = @"<br />@Html.ActionLink(""" + CodeGeneratorProperty.EntityPropertyName + @""", ""Index"", """ + CodeGeneratorProperty.EntityPropertyName + @""")";

                if (ViewIndexText.Contains(LinkSourceCode))
                {
                    // The link is already in the file,
                    // don't add the link.
                }
                else
                {
                    // Add the link to the end of the file.
                    StreamWriter sr = System.IO.File.AppendText(ViewIndexFileName);
                    sr.WriteLine();
                    sr.WriteLine(LinkSourceCode);
                    sr.Close();
                }
            }
            else
            {
                // the files not there don't do anything.
            }
        }


        private void JQueryCheck()
        {
 JQueryFigureOuter JQueryFigureOuter = new JQueryFigureOuter(Context);

            // See if there is some kind of JqueryUI installed
            if ( JQueryFigureOuter.FoundJQueryUIVersion )
            {
                // Yay
            }
            else
            {
                
                if ( JQueryFigureOuter.FoundJQueryVersion )
                {
                    // Try to install the same version of JQueryUI as JQuery
                    NuGetPackage JqueryUICombinedPackage = new NuGetPackage("jQuery.UI.Combined",
                                             JQueryFigureOuter.JQueryVersion,
                                             new NuGetSourceRepository());
                    try
                    {
                        var nugetService = (INuGetService)Context.ServiceProvider.GetService(typeof(INuGetService));
                        nugetService.InstallPackage(Context.ActiveProject, JqueryUICombinedPackage);
                    }
                    catch (Exception e)
                    {
                        System.Console.Out.Write(e);
                    }

                }
                else
                {
                    // Nothing's installed, install 1.10.2
                    NuGetPackage JqueryUICombinedPackage = new NuGetPackage("jQuery.UI.Combined",
                         "1.10.2",
                         new NuGetSourceRepository());
                    try
                    {
                        var nugetService = (INuGetService)Context.ServiceProvider.GetService(typeof(INuGetService));
                        nugetService.InstallPackage(Context.ActiveProject, JqueryUICombinedPackage);
                    }
                    catch (Exception e)
                    {
                        System.Console.Out.Write(e);
                    }
                }
            }

        }

        /// <summary>
        /// This method is executed after the ShowUIAndValidate method, and this is where the actual code generation should occur.
        /// In this example, we are generating a new file from t4 template based on the ModelType selected in our UI.
        /// </summary>
        public override void GenerateCode()
        {


            if (CodeGeneratorProperty.EntityPropertyName == null)
                return;

            if (CodeGeneratorProperty.InstallNuGet)
            {
                JQueryCheck();
            }

            if ( CodeGeneratorProperty.AddLinkToViewIndex )
            {
                UpdateHomeIndex();
            }

            foreach (EnvDTE.ProjectItem ProjectItem in Context.ActiveProject.ProjectItems)
            {
                if (ProjectItem.Name == "App_Start")
                {
                    foreach (EnvDTE.ProjectItem AppStart in ProjectItem.ProjectItems)
                    {
                        if (AppStart.Name == "BundleConfig.cs")
                        {
                            foreach (EnvDTE.Property Property in AppStart.Properties)
                            {
                                if (Property.Name == "FullPath")
                                {

                                    if (CodeGeneratorProperty.AddScriptBundle)
                                    {
                                        String FullPath = Property.Value.ToString();
                                        String Text = System.IO.File.ReadAllText(FullPath);

                                        if (Text.Contains("~/bundles/jqueryui"))
                                        {
                                            // no need to do anything
                                        }
                                        else
                                        {
                                            int IntRegisterBundles = Text.IndexOf("RegisterBundles");

                                            // 3 = { + CR + LF
                                            int FirstOpenBrace = Text.IndexOf("{", IntRegisterBundles) + 3;
                                            String FirstSection = Text.Substring(0, FirstOpenBrace);
                                            String SecondSection = Text.Substring(FirstOpenBrace, Text.Length - FirstOpenBrace);

                                            String S = "            bundles.Add(new ScriptBundle(\"~/bundles/jqueryui\").Include(" + Environment.NewLine +
                                                        "                        \"~/Scripts/jquery-ui-{version}.js\"));" + Environment.NewLine;
                                            String NewBundleConfig = FirstSection + S + SecondSection;
                                            System.IO.File.WriteAllText(FullPath, NewBundleConfig);
                                        }
                                    }

                                    if (CodeGeneratorProperty.AddStyleBundle)
                                    {

                                        String FullPath = Property.Value.ToString();
                                        String Text = System.IO.File.ReadAllText(FullPath);
                                        String StyleBundleContentThemesBaseCSS = "StyleBundle(\"~/Content/themes/base/css\")";
                                        if (Text.Contains(StyleBundleContentThemesBaseCSS))
                                        {
                                            // already there !
                                        }
                                        else
                                        {
                                            int LocationOfStyleBundleContentCSS = Text.IndexOf("StyleBundle(\"~/Content/css\")");

                                            // 3 = ; + CR + LR
                                            int LocationOfStyleBundleContentCSSBundleEnd = Text.IndexOf(";", LocationOfStyleBundleContentCSS) + 3;

                                            String FirstSection = Text.Substring(0, LocationOfStyleBundleContentCSSBundleEnd);
                                            String SecondSection = Text.Substring(LocationOfStyleBundleContentCSSBundleEnd, Text.Length - LocationOfStyleBundleContentCSSBundleEnd);

                                            String NewText = Environment.NewLine
                                          + "           bundles.Add(new StyleBundle(\"~/Content/themes/base/css\").Include( " + Environment.NewLine
                                          + "               \"~/Content/themes/base/jquery.ui.core.css\"," + Environment.NewLine
                                          + "               \"~/Content/themes/base/jquery.ui.datepicker.css\"," + Environment.NewLine
                                          + "               \"~/Content/themes/base/jquery.ui.theme.css\"));" + Environment.NewLine;

                                            String NewBundleConfig = FirstSection + NewText + SecondSection;
                                            System.IO.File.WriteAllText(FullPath, NewBundleConfig);
                                        }
                                    }
                                }
                            }
                        }
                    }
                }


                // Modify _Layout.cshtml
                if (ProjectItem.Name == "Views")
                {
                    foreach (EnvDTE.ProjectItem Views in ProjectItem.ProjectItems)
                    {
                        if (Views.Name == "Shared")
                        {
                            foreach (EnvDTE.ProjectItem Shared in Views.ProjectItems)
                            {
                                if ( Shared.Name == "_Layout.cshtml" )
                                {
                                    foreach (EnvDTE.Property Property in Shared.Properties)
                                    {
                                        if (Property.Name == "FullPath")
                                        {
                                            if (CodeGeneratorProperty.AddScriptLayout)
                                            {
                                                String FullPath = Property.Value.ToString();
                                                String Text = System.IO.File.ReadAllText(FullPath);

                                                String ScriptsRenderJQueryUI = "@Scripts.Render(\"~/bundles/jqueryui\")";
                                                String ScriptsRenderJQuery = "@Scripts.Render(\"~/bundles/jquery\")";

                                                if (Text.Contains(ScriptsRenderJQueryUI))
                                                {
                                                    // already there.
                                                }
                                                else
                                                {
                                                    int ScriptsLocation = Text.IndexOf(ScriptsRenderJQuery) + 2 + ScriptsRenderJQuery.Length;
                                                    String FirstSection = Text.Substring(0, ScriptsLocation);
                                                    String SecondSection = Text.Substring(ScriptsLocation, Text.Length - ScriptsLocation);

                                                    String S = "    " + ScriptsRenderJQueryUI + Environment.NewLine;
                                                    String NewLayoutCSHTML = FirstSection + S + SecondSection;
                                                    System.IO.File.WriteAllText(FullPath, NewLayoutCSHTML);
                                                }
                                            }

                                            if (CodeGeneratorProperty.AddStyleLayout)
                                            {
                                                String FullPath = Property.Value.ToString();
                                                String Text = System.IO.File.ReadAllText(FullPath);

                                                String ContentThemesBaseCSS = "@Styles.Render(\"~/Content/themes/base/css\")";

                                                if (Text.Contains(ContentThemesBaseCSS))
                                                {
                                                    // Nothing to do !
                                                }
                                                else
                                                {
                                                    String ContentCSS = "@Styles.Render(\"~/Content/css\")";
                                                    int EndOfContentCSSLocation = Text.IndexOf(ContentCSS) + ContentCSS.Length;

                                                    String FirstSection = Text.Substring(0, EndOfContentCSSLocation);
                                                    String SecondSection = Text.Substring(EndOfContentCSSLocation, Text.Length - EndOfContentCSSLocation);

                                                    String NewLayoutCSHTML = FirstSection + Environment.NewLine
                                                        + "    " + ContentThemesBaseCSS
                                                        + SecondSection;

                                                    System.IO.File.WriteAllText(FullPath, NewLayoutCSHTML);
                                                }
                                            }
                                        }
                                    }
                                }
                            }
                        }
                    }
                }
            }




            // find bundle config
            // see if it contains ~Scripts/jquery-ui
            // update if missing.           

            
            // Get the selected code type
            //var codeType = _viewModel.SelectedModelType.CodeType;

            //// Setup the scaffolding item creation parameters to be passed into the T4 template.
            //var parameters = new Dictionary<string, object>()
            //{
            //    { 
            //        /* This value should match the parameter in T4 */
            //        "ModelType", 
                    
            //        /* This is the value passed */ 
            //        codeType
            //    }

            //    //You can pass more parameters after they are defined in the template
            //};

            //// Add the custom scaffolding item from T4 template.
            //this.AddFileFromTemplate(Context.ActiveProject,
            //    "CustomCode",
            //    "CustomTextTemplate",
            //    parameters,
            //    skipIfExists: false);

            Dictionary<string, object> Parameters = new Dictionary<string, object>();
            Parameters.Add("CodeGeneratorProperties", CodeGeneratorProperty);

            this.AddFileFromTemplate(
                Context.ActiveProject,
                @"Controllers\" + CodeGeneratorProperty.EntityPropertyName + "Controller",
                "Controller",
                Parameters,
                skipIfExists: false);

            this.AddFileFromTemplate(
                Context.ActiveProject,
                @"Views\" + CodeGeneratorProperty.EntityPropertyName + @"\Create",
                "Create",
                Parameters,
                skipIfExists: false);

            this.AddFileFromTemplate(
                Context.ActiveProject,
                @"Views\" + CodeGeneratorProperty.EntityPropertyName + @"\Create",
                "Create",
                Parameters,
                skipIfExists: false);


            this.AddFileFromTemplate(
                Context.ActiveProject,
                @"Views\" + CodeGeneratorProperty.EntityPropertyName + @"\_CreateOrEdit",
                "CreateOrEdit",
                Parameters,
                skipIfExists: false);


            this.AddFileFromTemplate(
                Context.ActiveProject,
                @"Views\" + CodeGeneratorProperty.EntityPropertyName + @"\Index",
                "Index",
                Parameters,
                skipIfExists: false);


            this.AddFileFromTemplate(
                Context.ActiveProject,
                @"Models\Base\BasicIndexPage",
                "BasicIndexPage",
                Parameters,
                skipIfExists: false);

            this.AddFileFromTemplate(
                Context.ActiveProject,
                @"Models\" + CodeGeneratorProperty.EntityPropertyName + "Model",
                "Model",
                Parameters,
                skipIfExists: false);


            this.AddFileFromTemplate(
                Context.ActiveProject,
                @"Views\" + CodeGeneratorProperty.EntityPropertyName + @"\Delete",
                "DeleteHtml",
                Parameters,
                skipIfExists: false);


            this.AddFileFromTemplate(
                Context.ActiveProject,
                @"Views\" + CodeGeneratorProperty.EntityPropertyName + @"\Details",
                "DetailsHtml",
                Parameters,
                skipIfExists: false);


            this.AddFileFromTemplate(
                Context.ActiveProject,
                @"Views\" + CodeGeneratorProperty.EntityPropertyName + @"\Edit",
                "EditHtml",
                Parameters,
                skipIfExists: false);
            


            //this.AFFT(Context.ActiveProject,
            //    "CreateCSHtmlv1vv1v",
            //    "ControllerCS",
            //    Parameters,
            //    skipIfExists: false);

    //        this.AFFT(Context.ActiveProject,
    //"CreateOrEditcshtmlv1vv1v",
    //"CreateOrEditcshtml",
    //Parameters,
    //skipIfExists: false);


        }


        public void AFFT(Project project, string outputPath, string templateName, IDictionary<string, object> templateParameters, bool skipIfExists)
        {
            this.AddFileFromTemplate(project,outputPath,templateName,templateParameters, skipIfExists);
        }

    }
}
